"""SQL解析命令模块"""

import argparse
from pathlib import Path
from typing import Dict, Any, Tuple, Optional, Callable
from src.core.command import Command
from src.core.parser.factory import SQLParserFactory
from src.commands.preprocess_sql import PreprocessSQLCommand
from src.base.registry import bera
from src.base.sql_file_utils import SQLFileUtils
from src.base.project_config import ProjectConfig

class ParseSQLCommand(Command):
    """SQL解析命令"""

    def __init__(self):
        super().__init__()
        self.name = "parse-sql"
        self.group = "SQL处理"

    def add_arguments(self, parser: argparse.ArgumentParser) -> None:
        # 添加通用参数
        SQLFileUtils.add_arguments(parser)

    def execute(self, args: argparse.Namespace, callback: Optional[Callable[[], None]] = None) -> None:
        """执行命令"""
        try:
            bera.logger.info("开始执行parse-sql命令")

            # 先初始化项目配置
            ProjectConfig.init(args.project_dir)

            # 添加项目配置的sql-dir到搜索路径
            sql_dir = str(ProjectConfig.get_sql_dir())
            bera.logger.debug(f"添加项目配置的SQL目录到搜索路径: {sql_dir}")
            SQLFileUtils.add_search_path(sql_dir)

            # 执行callback
            if callback:
                callback()

            # 使用新的统一输入模式处理
            SQLFileUtils.execute_file_processing(args, self._process_sql_file)

            bera.logger.info("parse-sql命令执行完成")

        except Exception as e:
            bera.logger.error(f"parse-sql命令执行失败: {str(e)}")
            if args.verbose:
                import traceback
                traceback.print_exc()
            raise

    def _process_sql_file(self, filepath: str, args: argparse.Namespace) -> None:
        """处理单个SQL文件

        Args:
            filepath: SQL文件路径
            args: 命令行参数
        """
        try:
            # 从文件路径获取表名
            table_name = Path(filepath).stem
            bera.logger.info(f"处理表: {table_name}")

            # 确保预处理文件存在
            bera.logger.debug("检查预处理文件")
            formatted_sql_file = self._ensure_preprocessed_files(table_name, args)

            # 读取并解析SQL
            bera.logger.debug(f"读取SQL文件: {formatted_sql_file}")
            sql_content = SQLFileUtils.read_sql_file(str(formatted_sql_file))

            bera.logger.info("开始解析SQL")
            parser = SQLParserFactory.create("custom")
            sql_data = parser.parse_sql(sql_content)
            bera.logger.info("SQL解析完成")

            # 保存结果
            bera.logger.debug("保存解析结果")
            self._save_result(sql_data, table_name, args)

        except Exception as e:
            bera.logger.error(f"处理表失败: {table_name}")
            SQLFileUtils.handle_file_error(e, Path(filepath), table_name)
            raise

    def _ensure_preprocessed_files(self, table_name: str, args: argparse.Namespace) -> Path:
        """确保预处理文件存在"""
        # 获取表目录
        table_dir = SQLFileUtils.get_output_table_dir(table_name)
        sql_file = table_dir / "formatted.auto.sql"

        # 如果文件不存在,则执行预处理
        if not sql_file.exists():
            preprocess_cmd = PreprocessSQLCommand()
            preprocess_args = self._create_preprocess_args(table_name, args)
            preprocess_cmd.execute(preprocess_args)

        return sql_file

    def _create_preprocess_args(self, table_name: str, args: argparse.Namespace) -> argparse.Namespace:
        """创建预处理命令参数"""
        return type('Args', (), {
            'filename': table_name,
            'filepath': None,
            'directory': None,
            'output': str(SQLFileUtils.get_output_tables_dir()),
            'verbose': args.verbose,
            'format_create': False,
            'format_insert': False,
            'project_dir': args.project_dir
        })()

    def _save_result(self, result: Dict[str, Any], table_name: str, args: argparse.Namespace) -> None:
        """保存解析结果"""
        try:
            # 调整表级字段顺序，确保 indexes 在最后
            if "table" in result and "indexes" in result["table"]:
                indexes = result["table"].pop("indexes")
                result["table"]["indexes"] = indexes

            # 获取配置目录
            config_dir = SQLFileUtils.get_output_merge_dir(table_name)
            output_file = config_dir / "sql.json"

            # 保存结果
            SQLFileUtils.write_json_file(output_file, result)

        except Exception as e:
            bera.logger.error(f"保存解析结果失败: {str(e)}")
            SQLFileUtils.handle_file_error(e, output_file, table_name)
